import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import java.util.List;

/**
 * 游戏主函数
 * 
 * 需要实现的功能:
 *  1.初始化游戏窗口和菜单
 *  2.创建游戏控制按钮
 *  3.管理玩家手牌和出牌逻辑
 *  4.处理游戏流程（抢地主、出牌、判断胜负）
 *
 */

public class GameMain extends JFrame {
    // 窗口尺寸
    private static final int WINDOW_WIDTH = 830;
    private static final int WINDOW_HEIGHT = 620;

    // 游戏常量
    private static final int PLAYER_COUNT = 3;
    private static final int TOTAL_CARDS = 54;
    private static final int LANDLORD_CARDS = 3;
    
    // 游戏组件
    private     Container       container;                                      // todo 容器的作用？

    private     List<Card>[]    playerHands = new ArrayList[PLAYER_COUNT];      // 三个动态数组表示三位玩家手牌
    private     List<Card>      communityCards = new ArrayList<>();             // 一个动态数组表示地主牌
    private     JTextField[]    timers = new JTextField[PLAYER_COUNT];          // 三个文本框放置计时器

    private     JButton[]       actionButtons = new JButton[4];                 // 四个按键表示抢不抢地主，出不出牌
    private     JLabel          landownerIndicator;                             // 地主指示器
    
    // 游戏状态
    private     int             currentPlayer = 0;                              // 当前出牌玩家（0-左侧电脑，1-玩家自己，2-右侧电脑）
    private     int             landlordIndex = -1;                             // 地主玩家索引
    private     boolean         gameStarted = false;
    
    public GameMain() {
        initWindow();
        initMenu();
        initGameControls();
        initPlayers();
        initTimers();
        startNewGame();
        setVisible(true);
    }

    /**
     * 初始化游戏窗口
     */
    private void initWindow() {
        setTitle("斗地主游戏");
        setSize(WINDOW_WIDTH, WINDOW_HEIGHT);
        setResizable(false);
        setLocationRelativeTo(null); // 居中显示
        
        container = getContentPane();  // 获得内容面板
        container.setLayout(null); // 使用绝对布局
        container.setBackground(new Color(0, 112, 26)); // 绿色背景
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }

    /**
     * 初始化菜单系统
     */
    private void initMenu() {
        JMenuBar menuBar = new JMenuBar();

        JMenu gameMenu = new JMenu("游戏");
        JMenu helpMenu = new JMenu("帮助");

        JMenuItem newGameItem = new JMenuItem("新游戏");
        JMenuItem exitItem = new JMenuItem("退出");
        JMenuItem aboutItem = new JMenuItem("关于");

        
        newGameItem.addActionListener(e -> startNewGame());
        exitItem.addActionListener(e -> System.exit(0));
        aboutItem.addActionListener(e -> JOptionPane.showMessageDialog(this, "斗地主游戏 v1.0\n作者: Your Name"));
        
        gameMenu.add(newGameItem);
        gameMenu.addSeparator(); // TODO 作用？
        gameMenu.add(exitItem);
        helpMenu.add(aboutItem);
        
        menuBar.add(gameMenu);
        menuBar.add(helpMenu);
        setJMenuBar(menuBar);
    }

    /**
     * 初始化游戏控制按钮
     */
    private void initGameControls() {
        // 抢地主按钮
        actionButtons[0] = new JButton("抢地主");
        actionButtons[1] = new JButton("不抢");
        
        // 出牌按钮
        actionButtons[2] = new JButton("出牌");
        actionButtons[3] = new JButton("不要");
        
        // 设置按钮位置和大小
        int buttonWidth = 80;
        int buttonHeight = 30;
        int buttonY = 500;
        
        for (int i = 0; i < actionButtons.length; i++) {
            actionButtons[i].setBounds(350 + i * 90, buttonY, buttonWidth, buttonHeight);
            actionButtons[i].addActionListener(this::handleButtonAction);
            actionButtons[i].setVisible(false); // 初始隐藏
            container.add(actionButtons[i]);
        }
        
        // 初始化地主指示器
        landownerIndicator = new JLabel(new ImageIcon("images/dizhu.gif"));
        landownerIndicator.setSize(80, 72);
        landownerIndicator.setVisible(false);
        container.add(landownerIndicator);
    }

    /**
     * 初始化玩家
     */
    private void initPlayers() {
        for (int i = 0; i < PLAYER_COUNT; i++) {
            playerHands[i] = new ArrayList<>();
        }
    }

    /**
     * 初始化计时器
     */
    private void initTimers() {
        // 设置计时器位置
        Point[] positions = {
            new Point(140, 230),  // 左侧玩家
            new Point(374, 360),  // 自己
            new Point(620, 230)   // 右侧玩家
        };
        
        for (int i = 0; i < PLAYER_COUNT; i++) {
            timers[i] = new JTextField("倒计时: 0");
            timers[i].setBounds(positions[i].x, positions[i].y, 80, 20);
            timers[i].setEditable(false);
            timers[i].setVisible(false);
            container.add(timers[i]);
        }
    }

    /**
     * 开始新游戏
     */
    private void startNewGame() {
        // 重置游戏状态
        resetGameState();
        
        // 洗牌和发牌
        shuffleAndDealCards();
        
        // 开始抢地主阶段
        startLandownerSelection();
    }

    /**
     * 重置游戏状态
     */
    private void resetGameState() {
        // 清空玩家手牌
        for (int i = 0; i < PLAYER_COUNT; i++) {
            playerHands[i].clear();
        }
        
        // 清空地主牌
        communityCards.clear();
        
        // 隐藏按钮和指示器
        for (JButton button : actionButtons) {
            button.setVisible(false);
        }
        landownerIndicator.setVisible(false);
        
        // 隐藏计时器
        for (JTextField timer : timers) {
            timer.setVisible(false);
        }
        
        // 移除所有卡牌组件
        Component[] components = container.getComponents();
        for (Component comp : components) {
            if (comp instanceof Card) {
                container.remove(comp);
            }
        }
        
        // 重置游戏状态
        landlordIndex = -1;
        currentPlayer = 0;
        gameStarted = false;
    }

    /**
     * 创建并洗牌
     * @return 洗好的牌堆
     */
    private List<Card> createShuffledDeck() {
        List<Card> deck = new ArrayList<>(TOTAL_CARDS);
        
        // 创建标准扑克牌（52张）
        for (int suit = 1; suit <= 4; suit++) {
            for (int value = 1; value <= 13; value++) {
                String cardName = suit + "-" + value;
                deck.add(new Card(this, cardName, false));
            }
        }
        
        // 添加大小王
        deck.add(new Card(this, "5-14", false)); // 小王
        deck.add(new Card(this, "5-15", false)); // 大王
        
        // 洗牌
        Collections.shuffle(deck);
        
        // 添加所有卡牌到容器
        for (Card card : deck) {
            container.add(card);
        }
        
        return deck;
    }

    /**
     * 洗牌和发牌
     */
    private void shuffleAndDealCards() {
        List<Card> deck = createShuffledDeck();
        
        // 发牌给玩家
        for (int i = 0; i < TOTAL_CARDS - LANDLORD_CARDS; i++) {
            Card card = deck.get(i);
            int playerIndex = i % PLAYER_COUNT;
            playerHands[playerIndex].add(card);
            positionCard(card, playerIndex, i);
        }
        
        // 设置地主牌
        for (int i = TOTAL_CARDS - LANDLORD_CARDS; i < TOTAL_CARDS; i++) {
            Card card = deck.get(i);
            communityCards.add(card);
            card.setLocation(300 + (i - (TOTAL_CARDS - LANDLORD_CARDS)) * 80, 10);
        }
        
        // 排序玩家手牌并重新定位
        for (int i = 0; i < PLAYER_COUNT; i++) {
            CommonUtils.sortCards(playerHands[i]);
            repositionHand(i);
        }
    }

    /**
     * 定位单张卡牌
     * @param card 卡牌对象
     * @param playerIndex 玩家索引
     * @param cardIndex 卡牌索引
     */
    private void positionCard(Card card, int playerIndex, int cardIndex) {
        Point position = new Point();
        
        switch (playerIndex) {
            case 0: // 左侧玩家
                position.x = 50;
                position.y = 60 + cardIndex * 5;
                break;
            case 1: // 自己
                position.x = 180 + cardIndex * 7;
                position.y = 450;
                card.turnFront(); // 显示正面
                break;
            case 2: // 右侧玩家
                position.x = 700;
                position.y = 60 + cardIndex * 5;
                break;
        }
        
        card.setLocation(position);
    }

    /**
     * 重新定位玩家手牌
     * @param playerIndex 玩家索引
     */
    private void repositionHand(int playerIndex) {
        CommonUtils.repositionHand(this, playerHands[playerIndex], playerIndex);
    }

    /**
     * 开始抢地主阶段
     */
    private void startLandownerSelection() {
        // 显示抢地主按钮
        actionButtons[0].setVisible(true); // 抢地主
        actionButtons[1].setVisible(true); // 不抢
        
        // 启动玩家计时器
        startTimerForPlayer(1);
    }

    /**
     * 启动玩家计时器
     * @param playerIndex 玩家索引
     */
    private void startTimerForPlayer(int playerIndex) {
        timers[playerIndex].setVisible(true);
        new Thread(() -> {
            for (int i = 15; i >= 0; i--) {
                timers[playerIndex].setText("倒计时: " + i);
                
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
                
                // 如果玩家已操作，退出计时
                if (!timers[playerIndex].isVisible()) {
                    return;
                }
            }
            
            // 超时处理
            SwingUtilities.invokeLater(() -> {
                timers[playerIndex].setText("超时");
                handleLandlordTimeout(playerIndex);
            });
        }).start();
    }

    /**
     * 处理地主选择超时
     * @param playerIndex 玩家索引
     */
    private void handleLandlordTimeout(int playerIndex) {
        // 默认选择不抢
        actionButtons[1].doClick();
    }

    /**
     * 设置地主
     * @param playerIndex 地主玩家索引
     */
    private void setLandlord(int playerIndex) {
        landlordIndex = playerIndex;
        
        // 添加地主牌到地主玩家
        playerHands[playerIndex].addAll(communityCards);
        CommonUtils.sortCards(playerHands[playerIndex]);
        repositionHand(playerIndex);
        
        // 显示地主指示器
        showLandlordIndicator(playerIndex);
        
        // 开始游戏
        startGame();
    }

    /**
     * 显示地主指示器
     * @param playerIndex 玩家索引
     */
    private void showLandlordIndicator(int playerIndex) {
        Point position = new Point();
        
        switch (playerIndex) {
            case 0: // 左侧玩家
                position.setLocation(80, 0);
                break;
            case 1: // 自己
                position.setLocation(90, 440);
                break;
            case 2: // 右侧玩家
                position.setLocation(700, 0);
                break;
        }
        
        landownerIndicator.setLocation(position);
        landownerIndicator.setVisible(true);
    }

    /**
     * 开始游戏主循环
     */
    private void startGame() {
        gameStarted = true;
        
        // 隐藏地主选择按钮
        actionButtons[0].setVisible(false);
        actionButtons[1].setVisible(false);
        
        // 显示出牌按钮（仅对玩家自己）
        actionButtons[2].setVisible(true);
        actionButtons[3].setVisible(true);
        
        // 设置当前玩家为地主
        currentPlayer = landlordIndex;
        
        // 开始游戏循环
        nextTurn();
    }

    /**
     * 进入下一回合
     */
    private void nextTurn() {
        // 更新UI显示当前玩家
        highlightCurrentPlayer();
        
        if (currentPlayer == 1) {
            // 玩家回合 - 激活卡牌点击
            activatePlayerCards(true);
            startTimerForPlayer(1);
        } else {
            // 电脑回合 - 自动出牌
            computerPlay(currentPlayer);
        }
    }

    /**
     * 高亮显示当前玩家
     */
    private void highlightCurrentPlayer() {
        // 实现高亮逻辑（例如：改变玩家区域颜色或边框）
        // 此处简化实现
        for (int i = 0; i < PLAYER_COUNT; i++) {
            timers[i].setVisible(i == currentPlayer);
        }
    }

    /**
     * 激活玩家卡牌
     * @param active 是否激活
     */
    private void activatePlayerCards(boolean active) {
        for (Card card : playerHands[1]) {
            card.setClickable(active);
        }
    }

    /**
     * 电脑玩家出牌
     * @param playerIndex 电脑玩家索引
     */
    private void computerPlay(int playerIndex) {
        // 模拟思考时间
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
        
        // 简单的AI出牌逻辑
        List<Card> cardsToPlay = simpleAI(playerIndex);
        
        if (cardsToPlay != null && !cardsToPlay.isEmpty()) {
            playCards(playerIndex, cardsToPlay);
        } else {
            // 不出
            timers[playerIndex].setText("不要");
            moveToNextPlayer();
        }
    }

    /**
     * 简单的AI出牌策略
     * @param playerIndex 玩家索引
     * @return 要出的牌
     */
    private List<Card> simpleAI(int playerIndex) {
        // 简单策略：出最小的一张牌
        if (!playerHands[playerIndex].isEmpty()) {
            List<Card> play = new ArrayList<>();
            play.add(playerHands[playerIndex].get(0));
            return play;
        }
        return Collections.emptyList();
    }

    /**
     * 玩家出牌
     * @param playerIndex 玩家索引
     * @param cards 要出的牌
     */
    private void playCards(int playerIndex, List<Card> cards) {
        // 从玩家手中移除卡牌
        playerHands[playerIndex].removeAll(cards);
        
        // 重新定位玩家手牌
        repositionHand(playerIndex);
        
        // 定位出牌位置
        Point playPosition = getPlayCardPosition(playerIndex);
        for (Card card : cards) {
            CommonUtils.smoothMove(card, card.getLocation(), playPosition);
            playPosition.y += 15; // 堆叠显示
        }
        
        // 移动到下一玩家
        moveToNextPlayer();
    }

    /**
     * 获取出牌位置
     * @param playerIndex 玩家索引
     * @return 出牌位置
     */
    private Point getPlayCardPosition(int playerIndex) {
        Point position = new Point();
        
        switch (playerIndex) {
            case 0: // 左侧玩家
                position.setLocation(200, 200);
                break;
            case 1: // 自己
                position.setLocation(400, 300);
                break;
            case 2: // 右侧玩家
                position.setLocation(600, 200);
                break;
        }
        
        return position;
    }

    /**
     * 移动到下一玩家
     */
    private void moveToNextPlayer() {
        currentPlayer = (currentPlayer + 1) % PLAYER_COUNT;
        nextTurn();
    }

    /**
     * 处理按钮动作
     * @param e 动作事件
     */
    private void handleButtonAction(ActionEvent e) {
        Object source = e.getSource();
        
        if (source == actionButtons[0]) { // 抢地主
            handleGrabLandlord();
        } 
        else if (source == actionButtons[1]) { // 不抢
            handlePassLandlord();
        }
        else if (source == actionButtons[2]) { // 出牌
            handlePlayCards();
        }
        else if (source == actionButtons[3]) { // 不要
            handlePassTurn();
        }
    }

    /**
     * 处理抢地主
     */
    private void handleGrabLandlord() {
        // 隐藏计时器
        timers[1].setVisible(false);
        
        // 设置玩家为地主
        setLandlord(1);
    }

    /**
     * 处理不抢地主
     */
    private void handlePassLandlord() {
        // 隐藏计时器
        timers[1].setVisible(false);
        
        // 由电脑决定地主
        determineLandlordByAI();
    }

    /**
     * 由AI决定地主
     */
    private void determineLandlordByAI() {
        // 简单策略：选择牌力最强的玩家
        int bestPlayer = 0;
        int bestScore = calculateHandScore(playerHands[0]);
        
        for (int i = 1; i < PLAYER_COUNT; i++) {
            int score = calculateHandScore(playerHands[i]);
            if (score > bestScore) {
                bestPlayer = i;
                bestScore = score;
            }
        }
        
        setLandlord(bestPlayer);
    }

    /**
     * 计算手牌分数（用于决定地主）
     * @param hand 手牌
     * @return 分数
     */
    private int calculateHandScore(List<Card> hand) {
        int score = 0;
        
        for (Card card : hand) {
            String value = card.getCardName().substring(2);
            
            if ("2".equals(value)) score += 2;
            else if ("14".equals(value) || "15".equals(value)) score += 3; // 大小王
            else if ("1".equals(value)) score += 1; // A
        }
        
        return score;
    }

    /**
     * 处理出牌
     */
    private void handlePlayCards() {
        // 获取玩家选择的牌
        List<Card> selectedCards = new ArrayList<>();
        for (Card card : playerHands[1]) {
            if (card.isClicked()) {
                selectedCards.add(card);
            }
        }
        
        if (!selectedCards.isEmpty()) {
            // 验证牌型
            CardType cardType = CommonUtils.judgeCardType(selectedCards);
            if (cardType != CardType.INVALID) {
                playCards(1, selectedCards);
            } else {
                JOptionPane.showMessageDialog(this, "无效的牌型！");
            }
        }
    }

    /**
     * 处理跳过回合
     */
    private void handlePassTurn() {
        // 隐藏计时器
        timers[1].setVisible(false);
        
        // 显示"不要"
        timers[1].setText("不要");
        
        // 移动到下一玩家
        moveToNextPlayer();
    }

    public Container getContainer() {
        return container;
    }
    
    public static void main(String[] args) {
        SwingUtilities.invokeLater(GameMain::new);
    }
}